import { onBeforeUnmount } from 'vue'
import { debounce } from 'lodash'
export default function () {
    // dom监听key值
    const ATTR_NAME = 'resizeobserver-key';
    // 创建一个 ResizeObserver 实例
    const attrValueToCallback = {};
    // 配置项默认值
    const defaultOptions = {
        wait: 300,//防抖间隔时长
    }
    const resizeObserver = new ResizeObserver((entries) => {
        for (let entry of entries) {
            const resizedElement = entry.target
            const attrValue = resizedElement.getAttribute(ATTR_NAME);
            if (attrValue && attrValueToCallback[attrValue]) {
                const callback = attrValueToCallback[attrValue].callback;
                if (typeof callback === 'function') {
                    callback(entry)

                }
            }
        }
    });
    /**  
     * @param { Element } element  
     * @param { (ResizeObserverEntry) => {} } callback 
     * @param { Object } options  
     */
    const observe = (element, callback, options) => {
        if (!(element instanceof Element)) {
            console.error('GlobalResizeObserver, cannot observe non-Element.');
            return;
        }
        let attrValue = element.getAttribute(ATTR_NAME);
        if (!attrValue) {
            // 自定义attr key
            attrValue = String(new Date().getTime());
            element.setAttribute(ATTR_NAME, attrValue);
        }
        const optionsValue = Object.assign({}, defaultOptions, (options || {}));
        attrValueToCallback[attrValue] = {
            callback: debounce(callback, optionsValue.wait),
            options: optionsValue
        };
        // 监听元素
        resizeObserver.observe(element);
    }
    /**  
     * @param { Element } element  
     */
    const unobserve = (element) => {
        if (!(element instanceof Element)) {
            console.error('GlobalResizeObserver cannot unobserve non-Element.');
            return;
        }
        const attrValue = element.getAttribute(ATTR_NAME);
        if (!attrValue) {
            console.error('GlobalResizeObserver cannot unobserve element w/o ATTR_NAME.');
            return;
        }
        delete attrValueToCallback[attrValue];
        // 取消监听
        resizeObserver.unobserve(element);
    }

    // 取消全部监听
    onBeforeUnmount(() => {
        resizeObserver.disconnect();
    })
    return Object.freeze({ resizeObserver, observe, unobserve })
}